/*
 * WorkUnit.h
 *
 *  Created on: Apr 11, 2009
 *      Author: rpledge
 */

#ifndef WORKUNIT_H_
#define WORKUNIT_H_

#include <list>
#include <string>
#include <tr1/memory>

namespace ComputingObjects {

class WorkUnitData;
class WorkUnitResult;

class WorkUnitObserver;
typedef std::tr1::shared_ptr<WorkUnitObserver> SharedWorkUnitObserver;

class WorkUnit {
public:
	WorkUnit(std::string id, WorkUnitData& params);
	virtual ~WorkUnit();

	/*
	 * Called to compute the result of the work unit
	 */
	virtual void compute() = 0;

	enum state {
		idle, // Not assigned to a cluster yet
		pending, // Assigned to a cluster, not yet dispatched
		dispatched, // Work unit has been transmitted to the cluster, not yet computed
		executing, // The cluster has started executing the work unit
		completed, // The work unit has been computed, the result is still being recovered
		retrievable, // The result of the work unit is ready to be retrieved
	};
	static const char* stateString(enum state aState);
	
	enum state getState()
	{
		return myState;
	}
	
	/*
	 * Retrieve the result of a work unit
	 */
	virtual WorkUnitData& getResult() = 0;
	
	void attach(SharedWorkUnitObserver observer);
	void detach(SharedWorkUnitObserver observer);
	
	std::string getID()
	{
		return myID;
	}

	void setState(enum state);
	
private:
	enum state myState;
	std::string myID;
	std::list<SharedWorkUnitObserver> myObservers;
};

typedef std::tr1::shared_ptr<WorkUnit> SharedWorkUnit;


class WorkUnitObserver
{
public:
	WorkUnitObserver()
	{};
	
	virtual ~WorkUnitObserver()
	{};
	
	virtual void stateChange(WorkUnit& unit, enum WorkUnit::state previousState) = 0;
};

}

#endif /* WORKUNIT_H_ */
